package acs.bridge.jreport;

import acs.bridge.utility.UtilityParameters;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.type.WhenNoDataTypeEnum;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
//import org.springframework.jdbc.core.JdbcTemplate;

/**
 * Created by IntelliJ IDEA.
 * User: KuznetsovStV
 * Date: 24.12.11
 * Time: 11:14
 * Class for working with JasperReport
 */
public class JReport implements JReportInterface {
    Logger logger = Logger.getLogger(this.getClass().getName());
    private String whenNoDataType;

    public String getDbCommandLine() {
        return dbCommandLine;
    }

    private String dbCommandLine;

    public Properties getParameters() {
        return parameters;
    }

    private Properties parameters;

    public void setjReportExportInterface(JReportExportInterface jReportExportInterface) {
        this.jReportExportInterface = jReportExportInterface;
    }

    private JReportExportInterface jReportExportInterface;

    public void setjReportTemplateInterface(JReportTemplateInterface jReportTemplateInterface) {
        this.jReportTemplateInterface = jReportTemplateInterface;
    }

    private JReportTemplateInterface jReportTemplateInterface;

    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public static String getStackTrace(Throwable throwable) {
        Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        throwable.printStackTrace(printWriter);
        return writer.toString();
    }

    public void setReportFileName(String reportFileName) {
        this.reportFileName = reportFileName;
    }


    private String reportFileName;

    public String getPostfix() {

        SimpleDateFormat formatRU =
                new SimpleDateFormat("yyyyMMdd_HHmmss", new Locale("ru", "UA"));
        Calendar date = Calendar.getInstance();

        return "_" + formatRU.format(date.getTime());

    }

    public void addParameters(Properties parameters) {
        // Ищем недостающие и добавляем
        if   (parameters!=null)
        setParameters(UtilityParameters.combineProperties(getParameters(), parameters));
    }

    public void setDbCommandLine(String dbCommandLine) {
        this.dbCommandLine = dbCommandLine;
    }

    public void setDbCommandLineExt(String dbCommandLine) {
        if (this.dbCommandLine == null)
            setDbCommandLine(dbCommandLine);
    }

    public JReportItem makeReport() throws Exception {
        InputStream inputStream = null;
        ByteArrayOutputStream outputStream = null;
        JReportItem jReportItem = new JReportItem();

        /* Получаем параметры из bd */
        if (dbCommandLine != null && jdbcTemplate != null) {
            UtilityParameters.combineProperties(parameters, UtilityParameters.getParamRaw(jdbcTemplate.getDataSource().getConnection(), dbCommandLine));
        }

        // try {
        logger.info("Loading report ...");
        inputStream = jReportTemplateInterface.getBinaryStream();
        outputStream = new ByteArrayOutputStream();

        //  net.sf.jasperreports.compiler.xml.validation=false;

        if (parameters != null) {
            String l_set = null;
            Iterator it = parameters.keySet().iterator();
            logger.info("Parameters ...");
            while (it.hasNext()) {
                l_set = (String) it.next();
                logger.info("{param_name=" +
                        l_set +
                        ",param_value=" +
                        parameters.getProperty(l_set) + '}');
            }
        }

        logger.info("Compiling report ...");
        JasperReport jasperReport = JasperCompileManager.compileReport(inputStream);
        logger.info("Report compiled");
        if (whenNoDataType!=null)
        {
        try {

            WhenNoDataTypeEnum whenNoDataTypeEnum = WhenNoDataTypeEnum.valueOf(whenNoDataType);
            logger.info("WhenNoDataTypeEnum=" + whenNoDataTypeEnum);
            jasperReport.setWhenNoDataType(whenNoDataTypeEnum);
        } catch (IllegalArgumentException e) {
        }
    }

        logger.info("Filling report ...");
        Map<String, Object> map=null;
        if (parameters!=null)
         map = new HashMap<String, Object>((Map) parameters);

        JasperPrint jasperPrint =
                JasperFillManager.fillReport(jasperReport, map,jdbcTemplate.getDataSource().getConnection());


        logger.info("The number of pages " + jasperPrint.getPages().size());

        if (jasperPrint.getPages().size() > 0) {
            jReportItem.setReportData(jReportExportInterface.exportReport(jasperPrint));
            jReportItem.setReportName(reportFileName == null ? jReportTemplateInterface.getReportName() : reportFileName + getPostfix() + jReportExportInterface.getExtension());
            return jReportItem;
        } else
            return null;
    }

    public void setParameters(Properties parameters) {
        this.parameters = parameters;
    }


    public void setWhenNoDataType(String whenNoDataType) {
        this.whenNoDataType = whenNoDataType;
    }
}
